package com.autoagent.ai_live_master.common.utils;

import com.aliyun.oss.*;
import com.aliyun.oss.common.auth.DefaultCredentialProvider;
import com.aliyun.oss.common.comm.SignVersion;
import com.aliyun.oss.model.*;
import com.autoagent.ai_live_master.common.config.OssConfig;
import jakarta.annotation.PostConstruct;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

/**
 * 阿里云OSS工具类
 * 提供创建bucket、上传文件、下载文件、列出文件、删除文件、删除bucket等功能
 */
@Slf4j
@Data
@Component
public class OssUtil {

    private OSS ossClient;

    @Autowired
    private OssConfig ossConfig;


    /**
     * 初始化OSS客户端
     */
    @PostConstruct
    private void init() {
        createOssClient();
    }

    /**
     * 上传MultipartFile类型的文件
     * @param file MultipartFile文件
     * @return 是否上传成功
     */
    public String uploadLittleFile(MultipartFile file) {
        try {
            String bucket = ossConfig.getBucketName();

            String uuid = UUID.randomUUID().toString().replace("-", "");
            String extension = "";
            String originalName = file.getOriginalFilename();
            if (originalName.contains(".")) {
                extension = originalName.substring(originalName.lastIndexOf("."));
            }

            String objectName = uuid + extension;

            log.info("开始上传文件到OSS，bucket: {}, objectName: {}", bucket, objectName);
            ossClient.putObject(bucket, objectName, file.getInputStream());

            String endpointHost = ossConfig.getEndpoint().replaceFirst("^https?://", "");
            String fileUrl = "https://" + bucket + "." + endpointHost + "/" + objectName;

            log.info("文件上传成功，访问 URL: {}", fileUrl);
            return fileUrl;
        } catch (Exception e) {
            log.error("文件上传失败", e);
            return null;
        }
    }
    public String uploadLargeFile(MultipartFile file) {
        try {
            return uploadLargeFile(file.getInputStream(), file.getOriginalFilename());
        } catch (IOException e) {
            throw new RuntimeException("大文件上传失败：" + e.getMessage(), e);
        }
    }

    /**
     * 上传大文件（InputStream类型）
     * @param inputStream 输入流
     * @param originalFilename 原始文件名
     * @return 文件访问URL
     */
    public String uploadLargeFile(InputStream inputStream, String originalFilename) {
        String objectName = "";
        try {
            // 构建唯一文件名（带后缀）
            String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));
            objectName = "mmh/Ai_liva_master/" + UUID.randomUUID().toString() + suffix;

            // 将输入流读入字节数组以获取文件大小
            byte[] buffer = inputStream.readAllBytes();
            long fileSize = buffer.length;
            final long partSize = 1024 * 1024L; // 每片 1MB
            int partCount = (int) (fileSize / partSize);
            if (fileSize % partSize != 0) {
                partCount++;
            }

            // 初始化分片上传
            InitiateMultipartUploadRequest request = new InitiateMultipartUploadRequest(ossConfig.getBucketName(), objectName);
            InitiateMultipartUploadResult result = ossClient.initiateMultipartUpload(request);
            String uploadId = result.getUploadId();

            List<PartETag> partETags = new ArrayList<>();

            for (int i = 0; i < partCount; i++) {
                long skipBytes = i * partSize;
                long curPartSize = (i + 1 == partCount) ? (fileSize - skipBytes) : partSize;

                // 使用ByteArrayInputStream来处理分片
                ByteArrayInputStream partStream = new ByteArrayInputStream(buffer, (int)skipBytes, (int)curPartSize);

                UploadPartRequest uploadPartRequest = new UploadPartRequest();
                uploadPartRequest.setBucketName(ossConfig.getBucketName());
                uploadPartRequest.setKey(objectName);
                uploadPartRequest.setUploadId(uploadId);
                uploadPartRequest.setInputStream(partStream);
                uploadPartRequest.setPartSize(curPartSize);
                uploadPartRequest.setPartNumber(i + 1);

                UploadPartResult uploadPartResult = ossClient.uploadPart(uploadPartRequest);
                partETags.add(uploadPartResult.getPartETag());
                partStream.close();
            }
            // 完成上传
            CompleteMultipartUploadRequest completeRequest =
                    new CompleteMultipartUploadRequest(ossConfig.getBucketName(), objectName, uploadId, partETags);
            ossClient.completeMultipartUpload(completeRequest);

            // 拼接并返回访问 URL（例如：https://bucket.oss-cn-beijing.aliyuncs.com/uuid.jpg）
            String endpointHost = ossConfig.getEndpoint().replaceFirst("^https?://", "");
            return "https://" + ossConfig.getBucketName() + "." + endpointHost + "/" + objectName;

        } catch (Exception e) {
            throw new RuntimeException("大文件上传失败：" + e.getMessage(), e);
        }
    }

    /**
     * 创建OSS客户端
     */
    private void createOssClient() {
        try {
            // 创建ClientConfiguration实例
            ClientBuilderConfiguration clientConfig = new ClientBuilderConfiguration();
            // 设置签名版本为V4
            clientConfig.setSignatureVersion(SignVersion.V4);
            
            // 创建凭证提供者
            DefaultCredentialProvider credentialProvider = new DefaultCredentialProvider(
                    ossConfig.getAccessKeyId(), ossConfig.getAccessKeySecret());
            
            // 创建OSSClient实例
            ossClient = OSSClientBuilder.create()
                    .endpoint(ossConfig.getEndpoint())
                    .credentialsProvider(credentialProvider)
                    .region(ossConfig.getRegion())
                    .clientConfiguration(clientConfig)
                    .build();
        } catch (Exception e) {
            throw new RuntimeException("初始化OSS客户端失败", e);
        }
    }

    /**
     * 创建Bucket
     * @param bucketName Bucket名称，如果为空则使用配置文件中的默认值
     * @return 是否创建成功
     */
    public boolean createBucket(String bucketName) {
        try {
            log.info("开始创建Bucket: {}", bucketName);
            ossClient.createBucket(bucketName);
            log.info("Bucket创建成功");
            return true;
        } catch (OSSException | ClientException e) {
            log.error("创建Bucket失败", e);
            return false;
        }
    }

      /**
     * 下载文件
     * @param bucketName Bucket名称，如果为空则使用配置文件中的默认值
     * @param objectName 对象名称
     * @return 文件内容，如果下载失败则返回null
     */
    public String downloadFile(String bucketName, String objectName) {
        try {
            String bucket = bucketName == null || bucketName.isEmpty() ? ossConfig.getBucketName() : bucketName;
            log.info("开始从OSS下载文件，bucket: {}, objectName: {}", bucket, objectName);
            OSSObject ossObject = ossClient.getObject(bucket, objectName);
            InputStream contentStream = ossObject.getObjectContent();
            BufferedReader reader = new BufferedReader(new InputStreamReader(contentStream));
            StringBuilder stringBuilder = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null) {
                stringBuilder.append(line).append("\n");
            }
            reader.close();
            contentStream.close();
            log.info("文件下载成功");
            return stringBuilder.toString();
        } catch (OSSException | ClientException | IOException e) {
            log.error("文件下载失败", e);
            return null;
        }
    }

    /**
     * 列出Bucket中的文件
     * @param bucketName Bucket名称，如果为空则使用配置文件中的默认值
     * @return 文件列表
     */
    public List<OSSObjectSummary> listFiles(String bucketName) {
        try {
            String bucket = bucketName == null || bucketName.isEmpty() ? ossConfig.getBucketName() : bucketName;
            log.info("开始列出Bucket中的文件，bucket: {}", bucket);
            ObjectListing objectListing = ossClient.listObjects(bucket);
            List<OSSObjectSummary> files = objectListing.getObjectSummaries();
            log.info("成功获取文件列表，共{}个文件", files.size());
            return files;
        } catch (OSSException | ClientException e) {
            log.error("获取文件列表失败", e);
            return null;
        }
    }

    /**
     * 删除文件
     * @param bucketName Bucket名称，如果为空则使用配置文件中的默认值
     * @param objectName 对象名称
     * @return 是否删除成功
     */
    public boolean deleteFile(String bucketName, String objectName) {
        try {
            String bucket = bucketName == null || bucketName.isEmpty() ? ossConfig.getBucketName() : bucketName;
            log.info("开始删除文件，bucket: {}, objectName: {}", bucket, objectName);
            ossClient.deleteObject(bucket, objectName);
            log.info("文件删除成功");
            return true;
        } catch (OSSException | ClientException e) {
            log.error("文件删除失败", e);
            return false;
        }
    }

    /**
     * 删除Bucket
     * @param bucketName Bucket名称，如果为空则使用配置文件中的默认值
     * @return 是否删除成功
     */
    public boolean deleteBucket(String bucketName) {
        try {
            String bucket = bucketName == null || bucketName.isEmpty() ? ossConfig.getBucketName() : bucketName;
            log.info("开始删除Bucket: {}", bucket);
            ossClient.deleteBucket(bucket);
            log.info("Bucket删除成功");
            return true;
        } catch (OSSException | ClientException e) {
            log.error("删除Bucket失败", e);
            return false;
        }
    }

    /**
     * 从OSS URL中提取objectName
     * @param ossUrl OSS完整URL，例如：https://bucket.oss-region.aliyuncs.com/mmh/Ai_liva_master/uuid.txt
     * @return objectName，例如：mmh/Ai_liva_master/uuid.txt
     */
    public String extractObjectNameFromUrl(String ossUrl) {
        try {
            if (ossUrl == null || ossUrl.isEmpty()) {
                return null;
            }

            // OSS URL格式：https://bucket.oss-region.aliyuncs.com/objectName
            // 找到第三个斜杠后的内容就是objectName
            int protocolEnd = ossUrl.indexOf("://");
            if (protocolEnd == -1) {
                return null;
            }

            String afterProtocol = ossUrl.substring(protocolEnd + 3);
            int firstSlash = afterProtocol.indexOf("/");
            if (firstSlash == -1) {
                return null;
            }

            return afterProtocol.substring(firstSlash + 1);
        } catch (Exception e) {
            log.error("提取objectName失败: {}", e.getMessage());
            return null;
        }
    }

    /**
     * 关闭OSS客户端
     */
    public void shutdown() {
        if (ossClient != null) {
            ossClient.shutdown();
        }
    }
}